#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include "gaia_common.h"
#include "gaia_init_socket.h"


/* 主处理函数 */
int main (int argc, char * argv[]) 
{
  int listen_fd;
  int connect_fd;
  int stat;

  struct sockaddr_in server_addr;
  struct sockaddr_in client_addr;

  /* 对结构体清零 */
  bzero(&server_addr,sizeof(struct sockaddr_in));
  bzero(&client_addr,sizeof(struct sockaddr_in));

  /* 创建socket */
  if(gaia_init_socket(&listen_fd,&server_addr) == -1)
  {
    perror("init_socket() fail");
    exit(1);
  }

  socklen_t addrlen = sizeof(struct sockaddr_in);
  pid_t pid;

  while(1)
  {
    if( (connect_fd = accept(listen_fd,(struct sockaddr *)&client_addr,&addrlen)) == -1)
    {
      perror("accept fail");
      continue;
    }

    /* 父进程退出 */
    if( (pid = fork()) < 0 )
    {
      perror("fork() error!\n");
      exit(EXIT_FAILURE);
    }else if(pid == 0) //子进程处理请求
    {
      close(listen_fd);
      printf("pid %d process client request from %s : %d\n",getpid(),inet_ntoa(client_addr.sin_addr),htons(client_addr.sin_port));
      /* 处理请求 */
      if(gaia_process_request(&connect_fd,&client_addr) == -1)
      {
        perror("request process fail");
        shutdown(connect_fd,SHUT_RDWR);
        printf("pid %d loss connection to %s\n",getpid(),inet_ntoa(client_addr.sin_addr));
        _exit(EXIT_FAILURE); /* 从子进程退出,关闭这次请求处理 */
      }
      printf("Finish process reply!\n");
      printf("pid %d close connection to %s\n",getpid,inet_ntoa(client_addr.sin_addr));
      shutdown(connect_fd,SHUT_RDWR);
      //exit(EXIT_SUCCESS);
      return 0;
    }else
    {
      close(connect_fd);//关闭已经建立的连接
      printf("Send signal to child process (%d)\n", pid);
      //sleep(1);
      usleep(1000000); //100ms
      kill(pid, SIGKILL);
      wait(&stat);
      if(WIFSIGNALED(stat))
      {
        printf("Child process received signal (%d).\n", WTERMSIG(stat));
      }

      continue;
    }
    
  }

  shutdown(listen_fd,SHUT_RDWR);
  return 0;
}
